﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace RoketPack.IM
{
    class Manager
    {
        private Session m_Session = null;
        private Thread m_SessionThread = null;
        private RoketPack.Manager m_Manager = null;
        private FriendList m_FriendList = null;

        /// <summary>
        /// Creates a new IM manager.
        /// </summary>
        /// <param name="manager">The main RoketPack manager.</param>
        internal Manager(RoketPack.Manager manager)
        {
            this.m_Manager = manager;

            if (this.m_Manager.Settings.IMUsername != null && this.m_Manager.Settings.IMPassword != null && this.m_Manager.Settings.IMUsername.Contains("@"))
            {
                string[] s = this.m_Manager.Settings.IMUsername.Split(new char[] { '@' }, 2);
                this.m_Session = new Session(s[1], s[0], this.m_Manager.Settings.IMPassword);
            }
            this.m_FriendList = new FriendList(this.m_Session, this.m_Manager);
            this.m_FriendList.NotConfigured = false;
        }

        /// <summary>
        /// Starts the IM manager, beginning messaging loops and connecting
        /// to the remote server.
        /// </summary>
        internal void Start()
        {
            if (this.m_Session != null)
            {
                ThreadStart lambda = () =>
                    {
                        this.m_Session.Connect();
                    };
                this.m_SessionThread = new Thread(lambda);
                this.m_SessionThread.Name = "IM Session Manager";
                this.m_SessionThread.IsBackground = true;
                this.m_SessionThread.Start();
                this.m_FriendList.NotConfigured = false;
            }
            else
                this.m_FriendList.NotConfigured = true;

            this.m_FriendList.Show();
        }

        /// <summary>
        /// Reconnects to the server, possibly under a different username after
        /// the account settings have been updated.
        /// </summary>
        internal void Reconnect()
        {
            // Delete the old friend list.
            this.m_FriendList.Close();

            // Disconnect the existing session.
            if (this.m_Session != null)
                this.m_Session.Disconnect();

            // Create a new session object.
            if (this.m_Manager.Settings.IMUsername != null && this.m_Manager.Settings.IMPassword != null && this.m_Manager.Settings.IMUsername.Contains("@"))
            {
                string[] s = this.m_Manager.Settings.IMUsername.Split(new char[] { '@' }, 2);
                this.m_Session = new Session(s[1], s[0], this.m_Manager.Settings.IMPassword);
            }

            // Create a new friend list.
            this.m_FriendList = new FriendList(this.m_Session, this.m_Manager);

            // Start a new thread.
            if (this.m_Session != null)
            {
                ThreadStart lambda = () =>
                {
                    this.m_Session.Connect();
                };
                this.m_SessionThread = new Thread(lambda);
                this.m_SessionThread.Name = "IM Session Manager";
                this.m_SessionThread.IsBackground = true;
                this.m_SessionThread.Start();
                this.m_FriendList.NotConfigured = false;
            }
            else
                this.m_FriendList.NotConfigured = true;

            // Show the friend list.
            this.m_FriendList.Show();
        }

        /// <summary>
        /// Announces the execution of a specified application to all of
        /// the user's contacts.
        /// </summary>
        /// <param name="name">The application name.</param>
        internal void AnnounceApplicationExecution(string name)
        {
            this.m_Session.AnnounceApplicationExecution(name);
        }

        /// <summary>
        /// Clears all of the current notification windows shown.
        /// </summary>
        internal void ClearNotifications()
        {
            if (this.m_Session != null)
                this.m_Session.ClearNotifications();
        }

        /// <summary>
        /// Shows the friend list form.
        /// </summary>
        internal void Show()
        {
            if (this.m_FriendList != null)
                this.m_FriendList.Show();
        }

        /// <summary>
        /// Hides the friend list form.
        /// </summary>
        internal void Hide()
        {
            if (this.m_FriendList != null)
                this.m_FriendList.Hide();
        }

        /// <summary>
        /// Whether the friend list form is currently visible.
        /// </summary>
        internal bool Visible
        {
            get
            {
                if (this.m_FriendList == null)
                    return false;

                return this.m_FriendList.Visible;
            }
        }

        /// <summary>
        /// A reference to the current friend list form.
        /// </summary>
        internal FriendList Form
        {
            get
            {
                return this.m_FriendList;
            }
        }
    }
}
